const { CrdtText } = require("../crdt/crdttext.js");

// 客户端类
class Client {
  /**
   *
   * @param {*} id 客户端id
   */
  constructor(id) {
    this.id = id; // 当前客户端id
    this.text = new CrdtText(id); // 创建一个新的CrdtText实例对象
    this.history = []; // 用于记录已经执行的本地操作
  }

  /**
   * 返回当前的文本内容
   */
  value() {
    return this.text.value(); // 返回当前的文本内容，不包含被删除的字符
  }

  /**
   * 插入字符
   * @param {*} index 要插入的字符位置
   * @param {*} value 要插入的字符
   */
  insert(index, value) {
    const op = this.text.localInsert(index, value); // 插入操作完成拿到字符对象
    // 接下来需要做一个历史记录
    this.history.push({
      type: "insert",
      char: op,
    });
    console.log(
      `[${this.id}] 插入 '${value}' at ${index} => ${this.text.value()}`
    );
    return op; // 返回当前的字符对象
  }

  /**
   * 删除字符方法
   * @param {*} index 要删除的字符的位置
   */
  delete(index) {
    const op = this.text.localDelete(index); // 删除操作完成，拿到删除的字符对象
    // 接下来需要做一个历史记录
    this.history.push({
      type: "delete",
      id: op.id,
    });
    console.log(`[${this.id}] 删除 index ${index} => ${this.text.value()}`);
    return op; // 返回当前的字符对象
  }

  /**
   *
   * @param {*} handleDesc 操作描述对象
   * { type: "insert", char: op }
   * { type: "delete", id: op.id }
   */
  receive(handleDesc) {
    if (handleDesc.type === "insert") {
      // 说明要同步的操作是插入操作
      this.text.remoteInsert(handleDesc.char); // 远程插入
    } else if (handleDesc.type === "delete") {
      // 说明要同步的操作是删除操作
      this.text.remoteDelete(handleDesc.id); // 远程删除
    } else {
      throw new Error("操作类型不正确");
    }
    console.log(`[${this.id}] 同步操作 => ${this.text.value()}`);
  }
}

module.exports = {
  Client,
};
